/*
  light.cpp - simply abstract of OpenGL Lighting
  
*/

#include <gl/gl.h>

#define MAXSOURCE 8

void initlight ()
{
  glShadeModel (GL_SMOOTH);
  glEnable(GL_LIGHTING);
  glEnable(GL_DEPTH_TEST);
}

/* set global brightness
*/
extern void setbright (float amb)
{
  GLfloat ambient[] = {amb, amb, amb, 1.0f};
  
  glLightModelfv (GL_LIGHT_MODEL_AMBIENT, ambient);
}

/* turn on the light source id(0-7)
*/
extern void lighton (int id)
{
  if (id >= 0 && id < MAXSOURCE)
    glEnable (GL_LIGHT0 + id);
}

/* turn off the light souce id(0-7)
*/
extern void lightoff (int id)
{
  if (id >= 0 && id < MAXSOURCE)
    glDisable (GL_LIGHT0 + id);
}

/* set the strength of light ambient
*/
extern void setambient (int id, float value)
{
  if (id < 0 || id >= MAXSOURCE)
    return;
    
  GLfloat ambient[] = {value, value, value, 1.0f};
  
  glLightfv (GL_LIGHT0+id, GL_AMBIENT, ambient);
}

/* set the strength of light diffuse
*/
extern void setdiffuse (int id, float value)
{
  if (id < 0 || id >= MAXSOURCE)
    return;
    
  GLfloat diffuse[] = {value, value, value, 1.0f };
  
  glLightfv(GL_LIGHT0+id, GL_DIFFUSE, diffuse);
}

extern void setspecular (int id, float value)
{
  if (id < 0 || id >= MAXSOURCE)
    return;
    
  GLfloat specular[] = {value, value, value, 1.0 };
  
  glLightfv (GL_LIGHT0+id, GL_SPECULAR, specular);
}

/* set light position.
if w == 0 then it will be a direcional light source
else it's a positional source.
1 to fit with current coordinate system. 
*/
extern void setlightpos (int id, int x, int y, int z, int w = 1)
{
  if (id < 0 || id >= MAXSOURCE)
    return;
    
  GLint position[] = {x, y, z, w};
  glLightiv (GL_LIGHT0+id, GL_POSITION, position);
}

/* set light attenuation
*/
extern void setattenu (int id, float c, float l = 0.0, float q = 0.0)
{
  if (id < 0 || id >= MAXSOURCE)
    return;
    
  glLightf(GL_LIGHT0+id, GL_CONSTANT_ATTENUATION, c);
  glLightf(GL_LIGHT0+id, GL_LINEAR_ATTENUATION, l);
  glLightf(GL_LIGHT0+id, GL_QUADRATIC_ATTENUATION, q);
}

/* set to spot light source
default direction: face to screen
*/
extern void setspot (int id, float cutoff, float exp = 0.0, float dx = 0.0, float dy = 0.0, float dz = 1.0)
{
  int light = GL_LIGHT0 + id;
  
  if (id < 0 || id >= MAXSOURCE)
    return;
  
  glLightf(light, GL_SPOT_CUTOFF, cutoff);
  
  GLfloat direction[] = {dx, dy, dz};
  glLightfv (light, GL_SPOT_DIRECTION, direction);

  glLightfv (light, GL_SPOT_EXPONENT, &exp);
}
